﻿using CJiaBao.Core.Utils;
using Core.Configuration.Helper;
using Core.Configuration.Utils;
using Core.Sdk.Util;
using Core.Sdk.WeiXin.Domain.pay;
using Core.Sdk.WeiXin.Tool;
using Newtonsoft.Json;
using System.Diagnostics;

namespace BrnMall.Sdk.WeiXin
{
    /// <summary>
    /// 支付相关接口
    /// </summary>
    public class PaySdk
    {

        #region 服务商:分账
        /// <summary>
        /// 特约商户分账（单次分账）
        /// </summary>
        public static ResponseHandler ProfitSharing(PayInput mach, string transaction_id, string out_order_no, List<SharingReceiver> receivers)
        {
            if (receivers.Sum(x => x.amount) < 1)
                return new ResponseHandler(FailResult("分佣金额不能少于1分"));

            var req = new RequestHandler();
            req.init();
            req.setParameter("appid", mach.AppId);
            req.setParameter("mch_id", mach.MchId);
            req.setParameter("nonce_str", TenpayUtil.getNoncestr().ToLower());

            req.setParameter("sign_type", "HMAC-SHA256");
            req.setParameter("transaction_id", transaction_id);
            req.setParameter("out_order_no", out_order_no);         //商户分账单号，唯一（单次分账、多次分账、完结分账应使用不同的商户分账单号）
            req.setParameter("receivers", JsonConvert.SerializeObject(receivers));
            string sign = req.HMAC_ShA256("key", mach.MchKey);
            req.setParameter("sign", sign);
            var postData = req.parseXML();

            var url = $"https://api.mch.weixin.qq.com/secapi/pay/profitsharing";
            string xmlResult = HttpHelper.Post(new Uri(url), postData, mach.MchId, mach.CertPath);

            Log($"微信分账 request：\r\n {postData} \r\n response: \r\n {xmlResult}");
            return new ResponseHandler(xmlResult);
        }
        

        /// <summary>
        /// 查询分账结果
        /// </summary>
        /// <param name="openMath">服务商</param>
        /// <param name="mach">特约商户</param>
        /// <param name="transaction_id">微信交易流水</param>
        /// <param name="out_order_no">分账订单号</param>
        /// <returns></returns>
        public static string ProfitSharingQuery(PayInput openMath, string sub_mch_id, string transaction_id, string out_order_no)
        {
            var req = new RequestHandler();
            req.init();
            req.setParameter("mch_id", openMath.MchId);
            req.setParameter("sub_mch_id", sub_mch_id);
            req.setParameter("nonce_str", TenpayUtil.getNoncestr().ToLower());
            req.setParameter("transaction_id", transaction_id);
            req.setParameter("out_order_no", out_order_no);         //商户分账单号，唯一（单次分账、多次分账、完结分账应使用不同的商户分账单号）
            req.setParameter("sign_type", "HMAC-SHA256");
            string sign = req.HMAC_ShA256("key", openMath.MchKey);
            req.setParameter("sign", sign);

            var url = $"https://api.mch.weixin.qq.com/pay/profitsharingquery";
            string xmlResult = HttpHelper.Post(new Uri(url), req.parseXML(), openMath.MchId, openMath.CertPath);
            return xmlResult;
        }

        /// <summary>
        /// 完结分账(不需要分账调用此接口)
        /// </summary>
        /// <param name="mach"></param>
        /// <param name="transaction_id"></param>
        /// <param name="out_order_no"></param>
        /// <returns></returns>
        public static string FinishProfit(PayInput mach, string transaction_id, string out_order_no)
        {
            var req = new RequestHandler();
            req.init();
            req.setParameter("appid", mach.AppId);
            req.setParameter("mch_id", mach.MchId);
            req.setParameter("nonce_str", TenpayUtil.getNoncestr().ToLower());
            req.setParameter("transaction_id", transaction_id);
            req.setParameter("out_order_no", out_order_no);         //商户分账单号，唯一（单次分账、多次分账、完结分账应使用不同的商户分账单号）
            req.setParameter("sign_type", "HMAC-SHA256");
            req.setParameter("description", "分账完结");
            string sign = req.HMAC_ShA256("key", mach.MchKey);
            req.setParameter("sign", sign);

            var url = $"https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish";
            string xmlResult = HttpHelper.Post(new Uri(url), req.parseXML(), mach.MchId, mach.CertPath);
            Log($"完结分账 request：\r\n {req.parseXML()} \r\n response: \r\n {xmlResult}");
            return xmlResult;
        }

        /// <summary>
        /// 添加分账方
        /// </summary>
        /// <param name="req"></param>
        public static ResponseHandler AddReceiver(PayInput math, SharingReceiver receiver)
        {
            var req = new RequestHandler();
            req.init();
            req.setParameter("mch_id", math.MchId);
            req.setParameter("appid", math.AppId);
            req.setParameter("nonce_str", TenpayUtil.getNoncestr().ToLower());
            req.setParameter("sign_type", "HMAC-SHA256");
            req.setParameter("receiver", JsonConvert.SerializeObject(receiver));
            string sign = req.HMAC_ShA256("key", math.MchKey);
            req.setParameter("sign", sign);

            var postData = req.parseXML();
            var url = "https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver";
            string result = HttpHelper.PostAsync(url, postData).GetAwaiter().GetResult();

            Log($"添加分账人 request：\r\n {postData} \r\n response: \r\n {result}");
            return new ResponseHandler(result);
        }

        /// <summary>
        /// 分账退回
        /// </summary>
        /// <returns></returns>
        public static object RefundProfit(PayInput openMath, string sub_appid, string sub_mch_id, int amount, string out_order_no)
        {
            RequestHandler req = new RequestHandler();
            req.init();
            req.setParameter("appid", openMath.AppId);
            req.setParameter("mch_id", openMath.MchId);
            req.setParameter("sub_appid", sub_appid);
            req.setParameter("sub_mch_id", sub_mch_id);
            req.setParameter("nonce_str", TenpayUtil.getNoncestr().ToLower());
            req.setParameter("sign_type", "HMAC-SHA256");

            req.setParameter("out_order_no", out_order_no);             //商户分账单号
            req.setParameter("out_return_no", out_order_no);            //商户回退单号
            req.setParameter("return_account", sub_mch_id);             //回退方账号
            req.setParameter("return_account_type", "MERCHANT_ID");      //回退方类型
            req.setParameter("return_amount", amount.ToString());       //回退金额
            req.setParameter("description", "分账退款");
            string sign = req.HMAC_ShA256("key", openMath.MchKey);
            req.setParameter("sign", sign);

            var postData = req.parseXML();
            var url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn";
            var result = HttpHelper.Post(new Uri(url), req.parseXML(), openMath.MchId, openMath.CertPath);

            Log($"分账退款 request：\r\n {postData} \r\n response: \r\n {result}");
            return result;
        }
        #endregion


        public static string OrderQuery(PayInput payInput, string transaction_id)
        {
            RequestHandler req = new RequestHandler();
            req.init();
            req.setParameter("appid", payInput.AppId);
            req.setParameter("mch_id", payInput.MchId);
            if (!string.IsNullOrEmpty(payInput.SubMchId))
            {
                req.setParameter("sub_mch_id", payInput.SubMchId);
                req.setParameter("sub_appid", payInput.SubAppId);
            }

            req.setParameter("nonce_str", TenpayUtil.getNoncestr().ToLower());
            req.setParameter("transaction_id", transaction_id);                 //微信支付订单号
            string sign = req.CreateMd5Sign("key", payInput.MchKey);
            req.setParameter("sign", sign);          
            var postData = req.parseXML();
            var url = "https://api.mch.weixin.qq.com/pay/orderquery";
            var result = HttpHelper.Post(new Uri(url), req.parseXML());
            return result;
        }

        /// <summary>
        /// 返回错误消息
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static string FailResult(string msg)
        {
            return $"<xml><return_code><![CDATA[Fail]]></return_code><return_msg><![CDATA[{msg}]]></return_msg></xml>";
        }
        static void Log(string msg)
        {
            Trace.TraceInformation(msg);
            LogHelper.WriteLog("weixin", msg);
        }
    }
}
